/**
 * @author Da Mu
 * @version 1.1.0
 * @mail 317782199@qq.com
 */
import {
    WebSocketGateway,
    WebSocketServer,
    SubscribeMessage,
    MessageBody,
    ConnectedSocket,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { TemplateApiGameRoom } from '../TemplateApiGameSocketRoom/TemplateApiGame.room';
import { forwardRef, Inject, NotFoundException } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger as WinstonLogger } from 'winston';

let CID = '';

@WebSocketGateway({
    path: '/api/v1/ws',
    cors: {
        origin: '*'
    },
})
export class TemplateApiChatGateway {
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: WinstonLogger
    constructor(
        /**
         * @description Solving the problem of dependency injection and mutual cyclic dependencies
         */
        @Inject(forwardRef(() => TemplateApiGameRoom))
        private readonly gameRoom: TemplateApiGameRoom
    ) { };
    @WebSocketServer()
    server: Server;

    async handleConnection(@ConnectedSocket() client: Socket) {
        console.log(`客户端已连接: ${client.id}`);
        CID = client.id;
        this.gameRoom.SceneGameCount();
    };

    handleDisconnect(@ConnectedSocket() client: Socket) {
        console.log(`客户端已断开连接: ${client.id}`);
        if (this.gameRoom.schedulerRegistry.doesExist('cron', 'ghost')) {
            this.gameRoom.schedulerRegistry.deleteCronJob('ghost');
        };
        this.gameRoom.delGhostTask();
        this.gameRoom.delPlayerDataType();
        this.gameRoom.delSceneGameCount();
        this.gameRoom.delAIModelData();
        this.logger.info({ event: 'socketDisconnect', clientId: `${client.id}` });
    };

    /**
     * 
     * @param client 
     * @param data 
     * @description About Author Information
     */
    @SubscribeMessage('AdvertiseMessage')
    handleMessage(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: string,
    ): void {
        console.log(`收到消息: ${data}`);

        this.gameRoom.client = client;
        this.gameRoom.authorInformationAnnouncement(data);
    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Regarding system message prompts
     */
    @SubscribeMessage('AdvertiseCombatSysMessage')
    handleCombatSysMessage(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: string,
    ): void {
        console.log(`收到消息: ${data}`);

        this.gameRoom.client = client;
        this.gameRoom.targetMessage(data);
    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Monster based methods in private scene games
     */
    @SubscribeMessage('privateSceneGameMonsters')
    handleGame(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: string,
    ): void {
        console.log(`收到消息: ${client.id}: ${data}`);

        /** Create Zombies */
        if (data === 'BM') {
            this.gameRoom.client = client;
            this.gameRoom.sceneBrushingMonsters();
        };

        /** Refresh Zombies */
        if (data === 'LS') {
            this.gameRoom.operateGhostTask();
        };
    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Regarding the calculation of ghost blood strips in Private scene games
     */
    @SubscribeMessage('privateSceneGameGhostBloodBar')
    handleGameBloodBar(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any
    ): void {
        console.log(`收到消息: ${client.id}: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        /** Blood bar count */
        if (body.type === 'BC') {
            this.gameRoom.client = client;
            this.gameRoom.PumpkinWeaponsAndGhostInteractions(body.body);
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Regarding the initialization status of game scene players
     */
    @SubscribeMessage('SceneGamePlayerInit')
    handleSceneGameInit(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: string,
    ): void {
        console.log(`收到消息: ${data}`);

        if (data === 'NEW') {
            this.gameRoom.client = client;
            this.gameRoom.createPlayerDataType(CID);
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description About picking up equipment in game scenes
     */
    @SubscribeMessage('SceneGameEquipmentPicking')
    handleSceneGameEquipmentPicking(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any,
    ): void {
        console.log(`收到消息: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        if (body.type === 'EP') {
            this.gameRoom.client = client;
            this.gameRoom.createEquipmentPicking(body.body);
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description About Kill Ghost Counting in Game Scenarios
     */
    @SubscribeMessage('SceneGameKillGhostCount')
    handleSceneGameKillGhostCount(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any,
    ): void {
        console.log(`收到消息: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        if (body.type === 'KG') {
            this.gameRoom.client = client;
            this.gameRoom.createGameKillGhostCount(body.body);
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description About obtaining Ball in handheld mode in game scenes
     */
    @SubscribeMessage('SceneGame2DGetBall')
    handleSceneGame2DGetBall(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: string,
    ): void {
        console.log(`收到消息: ${data}`);

        if (data === 'GB') {
            this.gameRoom.client = client;
            this.gameRoom.createSceneGame2DGetBall();
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Regarding the bullet hitting RP to obtain brain in game scenes
     */
    @SubscribeMessage('SceneGame2DCountBall')
    handleSceneGame2DCountBall(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any,
    ): void {
        console.log(`收到消息: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        if (body.type === 'RP') {
            this.gameRoom.client = client;
            this.gameRoom.createSceneGame2DCountBall(body.body);
        };

    };

    /**
     * 
     * @param client 
     * @param data 
     * @description Regarding zombie dialogues in game scenes
     */
    @SubscribeMessage('SceneGameZombieChat')
    handleSceneGameZombieChat(
        @ConnectedSocket() client: Socket,
        @MessageBody() data: any,
    ): void {
        console.log(`收到消息: ${data}`);
        let body: any;
        try {
            body = JSON.parse(data);
        } catch (error) {
            body = data;
        };

        if (body.type === 'talk') {
            this.gameRoom.client = client;
            this.gameRoom.createSceneGameZombieChat(body.body);
        };

    };

};